/*
 ************************************************************************************************
 *                                                                                              *
 *  OSA cooperative RTOS for Microchip PIC-controllers: PIC10/12/16/18/24/dsPIC                 *
 *                                                                                              *
 *  URL:            http://wiki.pic24.ru/doku.php/en/osa/ref/intro                              *
 *                  http://picosa.narod.ru                                                      *
 *                                                                                              *
 *----------------------------------------------------------------------------------------------*
 *                                                                                              *
 *  File:           osa_mcc30.h                                                                 *
 *                                                                                              *
 *  Compilers:      HT-PICC STD                                                                 *
 *                  HT-PICC18 STD                                                               *
 *                  Microchip C18                                                               *
 *                  Microchip C30                                                               *
 *                                                                                              *
 *  Programmer:     Timofeev Victor                                                             *
 *                  osa@pic24.ru, testerplus@mail.ru                                            *
 *                                                                                              *
 *  Description:    MCC30 specific definitions                                                  *
 *                                                                                              *
 *                                                                                              *
 ************************************************************************************************
 */


#ifndef __OSAMCC30_H__
#define __OSAMCC30_H__



#if   defined(__PIC24F__)
#include <p24Fxxxx.h>
#elif defined(__PIC24H__)
#include <p24Hxxxx.h>
#elif defined(__dsPIC30F__)
#include <p30Fxxxx.h>
#elif defined(__dsPIC33F__)
#include <p33Fxxxx.h>
#else
#warning "WARNING! PIC type not defined!"
#endif




/************************************************************************************************
 *                                                                                              *
 *     Constants and types                                                                      *
 *                                                                                              *
 ************************************************************************************************/


#ifndef OS_SMSG_SIZE
#define OS_SMSG_SIZE    0   // We can not use sizeof() because it does not
                            // work with #ifdef directive
#endif

//------------------------------------------------------------------------------
// For all memory models pointer to code mast be 16-bit value (manual 5.6)
// (For model large used segment .handles)

typedef unsigned int                OST_CODE_POINTER;
#define OS_CODE_POINTER_SIZE        2






/************************************************************************************************
 *                                                                                              *
 *     Platform macros                                                                          *
 *                                                                                              *
 ************************************************************************************************/


#define _PIC18_ERRATA_NOP()
#define _SET_TASK_IRP()      // Empty macro for this type of PICs
#define OS_CLRWDT()   asm volatile(" clrwdt ")
#define OS_ClrWdt()   asm volatile(" clrwdt ")
#define OS_SLEEP()    asm volatile(" pwrsav #0  ")
#define OS_Sleep()    asm volatile(" pwrsav #0  ")
#define OS_IDLE()     asm volatile(" pwrsav #1  ")
#define OS_Idle()     asm volatile(" pwrsav #1  ")






/************************************************************************************************
 *                                                                                              *
 *     S C H E D U L E R                                                                        *
 *                                                                                              *
 ************************************************************************************************/


//------------------------------------------------------------------------------
#ifdef OS_ENABLE_CRITICAL_SECTION
//------------------------------------------------------------------------------

    #define SKIP_IF_IS_IN_CRITICAL_SECTION()                                        \
        asm volatile("   btsc    _OS_Flags, #2  ");                                 \
        asm volatile("   bra     2f             "); /*  SCHED_CHECK_ENABLE   */     \

    #define IF_IN_CRITICAL_SECTION_THEN_BREAK()                                     \
        asm volatile("   btsc    _OS_Flags, #2  ");                                 \
        asm volatile("   bra     6f             "); /*  SCHED_BREAK */              \

//------------------------------------------------------------------------------
#else
//------------------------------------------------------------------------------

    #define SKIP_IF_IS_IN_CRITICAL_SECTION()
    #define IF_IN_CRITICAL_SECTION_THEN_BREAK()

//------------------------------------------------------------------------------
#endif  // OS_ENABLE_CRITICAL_SECTION
//------------------------------------------------------------------------------




//------------------------------------------------------------------------------
#ifdef OS_ENABLE_TTIMERS
//------------------------------------------------------------------------------

    #define IF_NOT_OS_CHECK_DELAYS_GOTO_SCHED_CONTINUE()                            \
        asm volatile("   btss    _OS_state, #4          "); /*  bDelay          */  \
        asm volatile("   bra     $ + 6                  "); /*  SCHED_NO_DELAY  */  \
        asm volatile("   btss    _OS_state, #5          "); /* bCanContinue */      \
        asm volatile("   bra     5f   ;SCHED_CONTINUE   ");                         \
        asm volatile(";SCHED_NO_DELAY:                  ");                         \

//------------------------------------------------------------------------------
#else
//------------------------------------------------------------------------------

    #define IF_NOT_OS_CHECK_DELAYS_GOTO_SCHED_CONTINUE()

//------------------------------------------------------------------------------
#endif
//------------------------------------------------------------------------------



//------------------------------------------------------------------------------
#ifndef OS_DISABLE_PRIORITY
//------------------------------------------------------------------------------

    /********************************************************************************************
     *                                                                                          *
     *     P R I O R I T Y   M O D E   S C H E D U L E R                                        *
     *                                                                                          *
     ********************************************************************************************/

    // This macro is to determine were there any ready task or system is in idle state
    #define OS_IsIdle()     (!OS_IsInCriticalSection() && !OS_Flags.bBestTaskFound)

    #define OS_Sched()                                                                          \
    {                                                                                           \
        asm volatile("   bset    _OS_Flags, #3                      "); /* bCheckingTasks */    \
        asm volatile("   bclr    _OS_Flags, #4                      "); /* bBestTaskFound */    \
        asm volatile("   mov     #%0, w0"::"i"(OS_WORST_PRIORITY + 1));                         \
        asm volatile("   mov     w0, __OS_best_priority             ");                         \
                        SKIP_IF_IS_IN_CRITICAL_SECTION();                                       \
        asm volatile("   mov     __OS_LastTask, w0                  ");                         \
        asm volatile("   mov     w0, __OS_CurTask                   ");                         \
        asm volatile("                                              ");                         \
        asm volatile("1:;SCHED_REPEAT:                              ");                         \
        asm volatile("   mov     #%0, w0"::"i"(OS_TaskVars));                                   \
        asm volatile("   add     #%0, w0"::"i"((OS_TASKS-1)*sizeof(OST_TCB)));                  \
        asm volatile("   cp      __OS_CurTask                       ");                         \
        asm volatile("   bra     nc, $ + 8                          "); /* SCHED_INC_CUR_TASK */\
        asm volatile("   mov     #%0, w0"::"i"(OS_TaskVars)          );                         \
        asm volatile(" mov w0, __OS_CurTask                         ");                         \
        asm volatile("   bra     2f    ;SCHED_CHECK_ENABLE          ");                         \
        asm volatile(";SCHED_INC_CUR_TASK:                          ");                         \
        asm volatile("   mov     #%0, w0"::"i"(sizeof(OST_TCB)));                               \
        asm volatile("   add     __OS_CurTask                       ");                         \
        asm volatile("                                              ");                         \
        asm volatile("2:;SCHED_CHECK_ENABLE:                        ");                         \
        asm volatile("   mov     __OS_CurTask, w1                   ");                         \
        asm volatile("   mov     [w1], w0                           ");                         \
        asm volatile("   mov     w0, _OS_state                      ");                         \
        asm volatile("   btsc    _OS_state, #6                      "); /* bEnable */           \
        asm volatile("   btsc    _OS_state, #7                      "); /* bPaused */           \
        asm volatile("   bra     5f   ;SCHED_CONTINUE               ");                         \
        asm volatile("                                              ");                         \
        asm volatile("   and     #7, w0                             ");                         \
        asm volatile("   cp      __OS_best_priority                 ");                         \
        asm volatile("   bra     leu, 5f  ;SCHED_CONTINUE           ");                         \
        asm volatile("                                              ");                         \
        asm volatile("   btsc    _OS_state, #3                      "); /* bReady */            \
        asm volatile("   bra     4f    ;SCHED_SKIP_RUN              ");                         \
        asm volatile("3:;SCHED_RUN:                                 ");                         \
                        _OS_JumpToTask();                                                       \
                        _OS_SaveRetAddr();                                                      \
        asm volatile("   btss    _OS_Flags, #3                      "); /* bCheckingTasks */    \
        asm volatile("   bra     7f ;SCHED_END                      ");                         \
        asm volatile("                                              ");                         \
        asm volatile("4:;SCHED_SKIP_RUN:                            ");                         \
                        IF_NOT_OS_CHECK_DELAYS_GOTO_SCHED_CONTINUE();                           \
        asm volatile("   btss    _OS_state, #3                      "); /* bReady */            \
        asm volatile("   bra     5f   ;SCHED_CONTINUE               ");                         \
        asm volatile("   bset    _OS_Flags, #4                      "); /* bBestTaskFound */    \
        asm volatile("   mov     __OS_CurTask, w0                   ");                         \
        asm volatile("   mov     w0, __OS_BestTask                  ");                         \
        asm volatile("   mov     [w0], w1                           ");                         \
        asm volatile("   and     #7, w1                             ");                         \
        asm volatile("   mov     w1, __OS_best_priority             ");                         \
        asm volatile("   bra     z, 6f  ;SCHED_BREAK                ");                         \
        asm volatile("                                              ");                         \
        asm volatile("5:;SCHED_CONTINUE:                            ");                         \
                        IF_IN_CRITICAL_SECTION_THEN_BREAK();                                    \
        asm volatile("   mov     __OS_CurTask, w0                   ");                         \
        asm volatile("   cp      __OS_LastTask                      ");                         \
        asm volatile("   bra     nz, 1b ;SCHED_REPEAT               ");                         \
        asm volatile("                                              ");                         \
        asm volatile("6:;SCHED_BREAK:                               ");                         \
        asm volatile("   btss    _OS_Flags, #4                      "); /* bBestTaskFound */    \
        asm volatile("   bra     7f ;SCHED_END                      ");                         \
        asm volatile("   bclr    _OS_Flags, #3                      "); /* bCheckingTasks */    \
        asm volatile("   mov     __OS_BestTask, w0                  ");                         \
        asm volatile("   mov     w0, __OS_CurTask                   ");                         \
        asm volatile("   mov     w0, __OS_LastTask                  ");                         \
        asm volatile("   bra     3b    ;SCHED_RUN                   ");                         \
                                                                                                \
        asm volatile("7:    ;SCHED_END:                             ");                         \
    }

//------------------------------------------------------------------------------
#else   // OS_DISABLE_PRIORITY
//------------------------------------------------------------------------------

    /********************************************************************************************
     *                                                                                          *
     *     N O N   P R I O R I T Y   M O D E   S C H E D U L E R                                *
     *                                                                                          *
     ********************************************************************************************/

    #define OS_IsIdle()     0    // for non priority mode supposed that system always not in idle

    // Scheduler macro for NON PRIORITY MODE

    #define OS_Sched()                                                                          \
    {                                                                                           \
        asm volatile("   clr     __OS_temp                          ");                         \
                        SKIP_IF_IS_IN_CRITICAL_SECTION();                                       \
        asm volatile("   mov     #%0, w0"::"i"(OS_TaskVars));                                   \
        asm volatile("   add     #%0, w0"::"i"((OS_TASKS-1)*sizeof(OST_TCB)));                  \
        asm volatile("   cp      __OS_CurTask                       ");                         \
        asm volatile("   bra     nc, $ + 8                          "); /* SCHED_INC_CUR_TASK */\
        asm volatile("   mov     #%0, w0"::"i"(OS_TaskVars));                                   \
        asm volatile("   mov     w0, __OS_CurTask                   ");                         \
        asm volatile("   bra     2f    ;SCHED_CHECK_ENABLE          ");                         \
        asm volatile(";SCHED_INC_CUR_TASK:                          ");                         \
        asm volatile("   mov     #%0, w0"::"i"(sizeof(OST_TCB)));                               \
        asm volatile("   add     __OS_CurTask                       ");                         \
        asm volatile("                                              ");                         \
        asm volatile("2:;SCHED_CHECK_ENABLE:                        ");                         \
        asm volatile("   mov     __OS_CurTask, w1                   ");                         \
        asm volatile("   mov     [w1], w0                           ");                         \
        asm volatile("   mov     w0, _OS_state                      ");                         \
        asm volatile("   btsc    _OS_state, #6                      "); /* bEnable */           \
        asm volatile("   btsc    _OS_state, #7                      "); /* bPaused */           \
        asm volatile("   bra     5f   ;SCHED_CONTINUE               ");                         \
                        IF_NOT_OS_CHECK_DELAYS_GOTO_SCHED_CONTINUE();                           \
                        _OS_JumpToTask();                                                       \
                        _OS_SaveRetAddr();                                                      \
        asm volatile("5:;SCHED_CONTINUE                             ");                         \
    }



//------------------------------------------------------------------------------
#endif  // OS_DISABLE_PRIORITY
//------------------------------------------------------------------------------

//______________________________________________________________________________





/************************************************************************************************
 *                                                                                              *
 *     Context switching macros                                                                 *
 *                                                                                              *
 ************************************************************************************************/

/*
 ********************************************************************************
 *                                                                              *
 *  _OS_JumpToTask()                                                            *
 *                                                                              *
 *------------------------------------------------------------------------------*
 *                                                                              *
 *  description:        jump indirectly from kernel (OS_Sched) into task        *
 *                                                                              *
 ********************************************************************************
 */


#define _OS_JumpToTask()                                                                        \
    {                                                                                           \
        asm volatile("  push.d  w8                  ");                                         \
        asm volatile("  push.d  w10                 ");                                         \
        asm volatile("  push.d  w12                 ");                                         \
        asm volatile("  push.w  w14                 ");                                         \
        asm volatile("  rcall   $ + 12              "); /*  SCHED_GOTO_TASK     */              \
        asm volatile("  pop.w   w14                 ");                                         \
        asm volatile("  pop.d   w12                 ");                                         \
        asm volatile("  pop.d   w10                 ");                                         \
        asm volatile("  pop.d   w8                  ");                                         \
        asm volatile("  bra     9f                  "); /*  SCHED_SAVE_RET_ADDR */              \
                                                                                                \
        asm volatile(";SCHED_GOTO_TASK:             ");                                         \
        asm volatile("   mov     __OS_CurTask, w0   ");                                         \
        asm volatile("   mov.w   [w0++], w1         ");                                         \
        asm volatile("   mov     w1, _OS_state      ");                                         \
        asm volatile("   mov.w   [w0++], w2         "); /* task addr */                         \
                                                                                                \
        /* Restore registers (C30 manual 4.12 Function call conversions) */                     \
        asm volatile("  mov.d   [w0++], w8          ");                                         \
        asm volatile("  mov.d   [w0++], w10         ");                                         \
        asm volatile("  mov.d   [w0++], w12         ");                                         \
        asm volatile("  mov.w   [w0++], w14         ");                                         \
                                                                                                \
        asm volatile("  mov     [w0], w4            "); /* w15 value */                         \
        asm volatile("  mov     w15, [w0]           "); /* save stack pointer */                \
        asm volatile("  cp0     w4                  ");                                         \
        asm volatile("  bra     z, $ + #4           ");                                         \
        asm volatile("  mov     w4, w15             ");                                         \
                                                                                                \
        /* Put task address into stack and make return */                                       \
        asm volatile("  clr     w3                  ");                                         \
        asm volatile("  push.d  w2                  ");                                         \
        asm volatile("  return                      ");                                         \
    }



/*
 ********************************************************************************
 *                                                                              *
 *  _OS_SaveRetAddr()                                                           *
 *                                                                              *
 *------------------------------------------------------------------------------*
 *                                                                              *
 *  description:    Save task return address.                                   *
 *                                                                              *
 *  parameters:     WREG    - address high byte                                 *
 *                  FSR     - address low byte                                  *
 *                                                                              *
 ********************************************************************************
 */

#define _OS_SaveRetAddr()                                                                       \
    {                                                                                           \
        asm volatile("9:   ;SCHED_SAVE_RET_ADDR:    ");                                         \
                                                                                                \
        /* Save OS_State      */                                                                \
        asm volatile("   mov     __OS_CurTask, w2   ");                                         \
                                                                                                \
        /* Disable interrupts to avoid changing bDelay flag by interrupt */                     \
        asm volatile("   disi    #5                 ");                                         \
        asm volatile("   mov     [w2], w1           ");                                         \
        asm volatile("   bclr    w1, #3             ");  /* bReady */                           \
        asm volatile("   bclr    w1, #5             ");  /* bCanContinue */                     \
        asm volatile("   mov     #0x28, w0          ");  /* bReady | bCanContinue */            \
        asm volatile("   and     _OS_state, WREG    ");                                         \
        asm volatile("   ior     w1, w0, w1         ");                                         \
        asm volatile("   mov     w1, [w2]           ");                                         \
        /* Here interrupts are enabling     */                                                  \
    }









/************************************************************************************************
 *                                                                                              *
 *     Return from task to OS_Sched macros                                                      *
 *                                                                                              *
 ************************************************************************************************/


/*
 ********************************************************************************
 *                                                                              *
 *   Switch control routines:                                                   *
 *                                                                              *
 *    _OS_GetReturnPoint()                - exit from task and save context     *
 *                                                                              *
 *    _OS_ReturnNoSave()                  - exit withowt saving return address  *
 *                                                                              *
 *    _OS_CLEAR_READY()                   - exit with saving address and        *
 *                                          clearing bReady                     *
 *                                                                              *
 *    _OS_CLEAR_READY_SET_CANCONTINUE()   - exit without saving address and     *
 *                                          clearing bReady and bCanContinue    *
 *                                                                              *
 ********************************************************************************
 */

extern void _OS_SchedRetPoint (void);
extern void _OS_SchedRetPointNoSave (void);
extern void _OS_CLEAR_READY (void);
extern void _OS_CLEAR_READY_SET_CANCONTINUE (void);

#define _OS_SET_FSR_CUR_TASK_W()
#define _OS_SET_FSR_CUR_TASK()


//------------------------------------------------------------------------------
#define _OS_GetReturnPoint()                    _OS_SchedRetPoint()
#define _OS_ReturnNoSave()                      _OS_SchedRetPointNoSave()
//------------------------------------------------------------------------------





























/******************************************************************************************
 *
 *  WORK WITH DYNAMIC TIMERS
 *
 ******************************************************************************************/

//------------------------------------------------------------------------------
#ifdef OS_ENABLE_DTIMERS
//------------------------------------------------------------------------------

//------------------------------------------------------------------------------
#if   OS_DTIMER_SIZE == 1
//------------------------------------------------------------------------------

    #define OS_INC_DTIMER()                                                             \
        {                                                                               \
            asm volatile("   mov     [w0 + #4], w2   ");                                \
            asm volatile("   inc     w2, w2          ");                                \
            asm volatile("   and     #0xFF, w2       ");                                \
            asm volatile("   mov     w2, [w0 + #4]   ");                                \
        }

//------------------------------------------------------------------------------
#elif OS_DTIMER_SIZE == 2
//------------------------------------------------------------------------------

    #define OS_INC_DTIMER()                                                             \
        {                                                                               \
            asm volatile("   mov     [w0 + #4], w2   ");                                \
            asm volatile("   inc     w2, w2          ");                                \
            asm volatile("   mov     w2, [w0 + #4]   ");                                \
        }

//------------------------------------------------------------------------------
#elif OS_DTIMER_SIZE == 4
//------------------------------------------------------------------------------

    #define OS_INC_DTIMER()                                                             \
        {                                                                               \
            asm volatile("   mov     [w0 + #4], w2   ");                                \
            asm volatile("   inc     w2, w2          ");                                \
            asm volatile("   mov     w2, [w0 + #4]   ");                                \
            asm volatile("   bra     NZ,_OS_DTIMERS_WORK_NEXT      ");                  \
            asm volatile("   mov     [w0 + #6], w2   ");                                \
            asm volatile("   inc     w2, w2          ");                                \
            asm volatile("   mov     w2, [w0 + #6]   ");                                \
        }

//------------------------------------------------------------------------------
#endif
//------------------------------------------------------------------------------




#define __OS_DTimersWork()                                                              \
    {                                                                                   \
        asm volatile("   mov     #__OS_DTimers, w0       ");                            \
        asm volatile("   mov     [w0], w1                "); /* w1 = flags */           \
        asm volatile("_OS_DTIMERS_WORK_NEXT:             ");                            \
        asm volatile("   btss    w1, #3                  "); /* check bNextEnable */    \
        asm volatile("   goto    _OS_DTIMERS_WORK_END    ");                            \
        asm volatile("   mov     [w0 + #2], w0           ");                            \
        asm volatile("   mov     [w0], w1                "); /* w1 = flags */           \
        asm volatile("   btss    w1, #2                  "); /* check bRun */           \
        asm volatile("   goto    _OS_DTIMERS_WORK_NEXT   ");                            \
        OS_INC_DTIMER();                                                                \
        asm volatile("   bra     NZ,_OS_DTIMERS_WORK_NEXT");                            \
        asm volatile("   bset    w1, #0                  "); /* set timeout */          \
        asm volatile("   mov     w1, [w0]                "); /* save flags */           \
        asm volatile("   bra     _OS_DTIMERS_WORK_NEXT   ");                            \
        asm volatile("_OS_DTIMERS_WORK_END:              ");                            \
    }


//------------------------------------------------------------------------------
#endif  // OS_ENABLE_DTIMER
//------------------------------------------------------------------------------








//______________________________________________________________________________
/******************************************************************************************
 *
 * MACROS FOR STATIC TIMERS WORK
 *
 ******************************************************************************************/

//------------------------------------------------------------------------------
#ifdef OS_ENABLE_STIMERS
//------------------------------------------------------------------------------


//------------------------------------------------------------------------------
#if     OS_STIMER_SIZE == 1
//------------------------------------------------------------------------------

    #define __OS_STimerWork(STIMER_ID, L)                                           \
        {                                                                           \
            asm volatile("  btsc.b     _OS_STimers + %0, #7"::"i"(STIMER_ID));      \
            asm volatile("  inc.b      _OS_STimers + %0    "::"i"(STIMER_ID));      \
        }

//------------------------------------------------------------------------------
#elif   OS_STIMER_SIZE == 2
//------------------------------------------------------------------------------

    #define __OS_STimerWork(STIMER_ID, L)                                           \
        {                                                                           \
            asm volatile("  btsc       _OS_STimers + %0,#15"::"i"(STIMER_ID*2));    \
            asm volatile("  inc        _OS_STimers + %0    "::"i"(STIMER_ID*2));    \
        }

//------------------------------------------------------------------------------
#elif   OS_STIMER_SIZE == 4
//------------------------------------------------------------------------------

    #define __OS_STimerWork(STIMER_ID, L)                                           \
        {                                                                           \
            asm volatile("  btss       _OS_STimers + %0,#15"::"i"(STIMER_ID*4+2));  \
            asm volatile("  bra        0f                                       "); \
            asm volatile("  inc        _OS_STimers + %0    "::"i"(STIMER_ID*4));    \
            asm volatile("  bra        nc, 0f                                   "); \
            asm volatile("  inc        _OS_STimers + %0    "::"i"(STIMER_ID*4+2));  \
            asm volatile("0:                                                    "); \
        }

//------------------------------------------------------------------------------
#endif  // OS_STIMER_SIZE
//------------------------------------------------------------------------------



//------------------------------------------------------------------------------
#endif  // OS_ENABLE_STIMERS
//------------------------------------------------------------------------------






//______________________________________________________________________________
/******************************************************************************************
 *
 * MACROS FOR OLD STYLE STATIC TIMERS WORK
 *
 ******************************************************************************************/

//------------------------------------------------------------------------------

#define __OS_Timer8Work(TIMER_ID,L)                                                                                 \
{                                                                                                               \
    asm volatile("   btss   _OS_Timeouts + #%0, #%1"::"i"((TIMER_ID >> _OST_INT_SHIFT)),"i"(TIMER_ID & _OST_INT_MASK));    \
    asm volatile("   bra    $ + #12 ");                                                                                   \
    asm volatile("   mov.b    _OS_Timers8+%0, wreg"::"i"(TIMER_ID));                                                     \
    asm volatile("   inc.b    w0, w0     ");                                                                             \
    asm volatile("   mov.b    wreg, _OS_Timers8+%0"::"i"(TIMER_ID));                                                     \
    asm volatile("   bra    NZ, $ + #4");                                                                                \
    asm volatile("   bclr   _OS_Timeouts + #%0, #%1"::"i"((TIMER_ID >> _OST_INT_SHIFT)),"i"(TIMER_ID & _OST_INT_MASK));      \
}

//------------------------------------------------------------------------------

#define __OS_Timer16Work(TIMER_ID,L)                                                                                \
{                                                                                                               \
    asm volatile("   btss   _OS_Timeouts + #%0, #%1"::"i"(((TIMER_ID+_OS_TIMER16_POS) >> _OST_INT_SHIFT)),"i"((TIMER_ID+_OS_TIMER16_POS) & _OST_INT_MASK));    \
    asm volatile("   bra    $ + #12 ");                                                                                   \
    asm volatile("   mov    _OS_Timers16+%0, w0"::"i"((TIMER_ID)*2));                                                    \
    asm volatile("   inc    w0, w0     ");                                                                               \
    asm volatile("   mov    w0, _OS_Timers16+%0"::"i"((TIMER_ID)*2));                                                    \
    asm volatile("   bra    NZ, $ + #4");                                                                                \
    asm volatile("   bclr   _OS_Timeouts + #%0, #%1"::"i"(((TIMER_ID+_OS_TIMER16_POS) >> _OST_INT_SHIFT)),"i"((TIMER_ID+_OS_TIMER16_POS) & _OST_INT_MASK));      \
}

//------------------------------------------------------------------------------

#define __OS_Timer24Work(TIMER_ID,L)                                                                                \
{                                                                                                               \
    asm volatile("   btss   _OS_Timeouts + #%0, #%1"::"i"(((TIMER_ID+_OS_TIMER24_POS) >> _OST_INT_SHIFT)),"i"((TIMER_ID+_OS_TIMER24_POS) & _OST_INT_MASK));    \
    asm volatile("   bra    $ + 12 ");                                                                                   \
    asm volatile("   mov    _OS_Timers24+%0, w0"::"i"((TIMER_ID)*2));                                    \
    asm volatile("   inc    w0, w0     ");                                                                               \
    asm volatile("   mov    w0, _OS_Timers24+%0"::"i"((TIMER_ID)*2));                                    \
    asm volatile("   bra    NZ, $ + #4");                                                                                \
    asm volatile("   bclr   _OS_Timeouts + #%0, #%1"::"i"(((TIMER_ID+_OS_TIMER24_POS) >> _OST_INT_SHIFT)),"i"((TIMER_ID+_OS_TIMER24_POS) & _OST_INT_MASK));      \
}

//------------------------------------------------------------------------------

#define __OS_Timer32Work(TIMER_ID,L)                                                                                \
{                                                                                                               \
    asm volatile("   btss   _OS_Timeouts + #%0, #%1"::"i"(((TIMER_ID+_OS_TIMER32_POS) >> _OST_INT_SHIFT)),"i"((TIMER_ID+_OS_TIMER32_POS) & _OST_INT_MASK));    \
    asm volatile("   bra    $ + #20 ");                                                                                   \
    asm volatile("   mov    _OS_Timers32+%0, w0"::"i"((TIMER_ID+_OS_TIMER32_POS)*4));                                    \
    asm volatile("   inc    w0, w0     ");                                                                               \
    asm volatile("   mov    w0, _OS_Timers32+%0"::"i"((TIMER_ID+_OS_TIMER32_POS)*4));                                    \
    asm volatile("   bra    NZ, $ + #12");                                                                                \
    asm volatile("   mov    _OS_Timers32+%0, w0"::"i"((TIMER_ID+_OS_TIMER32_POS)*4 + 2));                                \
    asm volatile("   inc    w0, w0     ");                                                                               \
    asm volatile("   mov    w0, _OS_Timers32+%0"::"i"((TIMER_ID+_OS_TIMER32_POS)*4 + 2));                                \
    asm volatile("   bra    NZ, $ + #4");                                                                                \
    asm volatile("   bclr   _OS_Timeouts + #%0, #%1"::"i"(((TIMER_ID+_OS_TIMER32_POS) >> _OST_INT_SHIFT)),"i"((TIMER_ID+_OS_TIMER32_POS) & _OST_INT_MASK));    \
}







#endif















